/*
Copyright (C) 2015 Marien Raat

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <perlinNoise.h>

// This class generates fractal noise. Fractal noise is a fractal like
// form of noise generated by adding multiple perlin noise maps with
// different feature sizes together. This class simplifies generating
// fractal noise from perlin noise. It can generate standard fractal
// noise and custom fractal noise from a list of values.
class FractalNoiseGenerator {
public:
    // The constructor of the class
    FractalNoiseGenerator(std::mt19937 *mt);
    ~FractalNoiseGenerator();

    // Generates a standard fractal noise map and saves it in
    // this->noiseMap. The strength of every feature size is
    // proportional to the root of the feature size. It will sum up
    // maps with a feature size down to 2 unless otherwise
    // specified. The largest feature size is always min(width,
    // height).  No more maps will be added once a feature size that
    // isn't a divisor of one of the sides is encountered.
    void generateStandardFractalNoise(
        // The width and height of the fractal noise map
        unsigned width,
        unsigned height,
        // This describes to what power the feature size will be
        // raised before the map is multiplied with the result.
        // A high value will result in a smooth map and a
        // low value will result in a rough maps.
        double powerFeatureSizeMultiplier,
        // The smalles feature size summed up in the map
        unsigned smallestFeatureSize = 2,
        // Whether to overwrite the previous fractal noise map or
        // allocate new space.
        // If the fractal noise map size is different from the previous
        // size this decides whether the old map will be deleted,
        // since new space needs to be allocated regardless.
        bool overwriteOldMap = true);

    // Generates a fractal noise map based on the passed values
    // array. In this array every two values represent one perlin
    // noise map to be added to the fractal noise map. The first value
    // of these two represents the feature size of the perlin map and
    // the second value represents the weight of this map. The map
    // will be multiplied by this weight, before it is added.
    void generateFractalNoiseFromValues(
        // The values that represent the perlin noise maps to be added
        // together.
        double *values,
        // The length of the values array. So this is 2 times the
        // ammount of maps that will be added unto eachother.
        unsigned ammountOfValues,
        // The width and height of the fractal noise map
        unsigned width,
        unsigned height,
        // Whether to overwrite the previous fractal noise map or
        // allocate new space.
        // If the fractal noise map size is different from the previous
        // size this decides whether the old map will be deleted,
        // since new space needs to be allocated regardless.
        bool overwriteOldMap = true);

    // The noise map that wil be generated by calling either
    // generateStandardFractalNoise or generateFractalNoiseFromValues
    double *noiseMap;
private:
    bool firstNoiseMap;
    unsigned previousWidth, previousHeight;
    PerlinNoiseGenerator *perlinNoiseGenerator;
};
